#include <boost/asio/error.hpp>
#include <boost/system/error_code.hpp>
#include <chrono>
#include<future>
#include "./include/rest_rpc.hpp"
#include "include/rest_rpc/client_util.hpp"
#include "include/rest_rpc/rpc_client.hpp"
#include "include/rest_rpc/use_asio.hpp"
#include <iostream>
#include<thread>


//回调重载版
// template<size_t TIMEOUT = DEFAULT_TIMEOUT, typename... Args>
// void async_call(const std::string& rpc_name,
//                 std::function<void(boost::system::error_code, string_view)> cb,
//                 Args&&... args);
//超时后框架自动把 ec == boost::asio::error::timed_out 发给你的回调； 
//需要使用条件变量完成同步 / 调用run来join
int main()
{
      std::mutex mtx;
      std::condition_variable cv;
      bool done = false;
      rest_rpc::rpc_client cli("127.0.0.1",8082);
      cli.connect();
      //2000ms超时
      cli.async_call<2000>("add",[&](boost::system::error_code ec,string_view data){
            if(ec == boost::asio::error::timed_out)
            {
                std::cerr << "RPC TimeFailed" << std::endl;
                return;
            }
            if(ec)
            {
                std::cout << "RPC error" << ec.message() << "\n";
                return;
            }
            int x = rest_rpc::get_result<int>(data);
            std::cout << "res: " << x << std::endl;
            done = true;
            cv.notify_one();
      },3,4);
      //注意由于是异步返回，因此我们可能拿到结果之前程序就退出了
      std::unique_lock<std::mutex> lk(mtx);
      cv.wait(lk,[&done](){
        return done == true;
    });
      return 0; 
}

//异步""阻塞"版
int mai1n()
{

    rest_rpc::rpc_client cli("127.0.0.1",8082);
    cli.connect();
    //1.future版本 std::future 本身自带等待超时接口
    auto fu = cli.async_call<rest_rpc::FUTURE>("add",3,4);
    //等待2秒
    if(fu.wait_for(std::chrono::seconds(2)) == std::future_status::timeout)
    {
        std::cerr << "call timer out" << std::endl; //超时
        return 0;
    }
    int val = fu.get().as<int>();
    std::cout << "result: " << val << std::endl; 
    return 0;
}